home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
apidev
/
ndr3.exe
/
VERODI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-14
|
12KB
|
403 lines
/*
VERODI.C shows how to obtain the version numbers (etc)
from ODI components using ODI API calls.
Author: Tim Farley
Copyright 1993, Tim Farley, All Rights Reserved
*/
#include <stdlib.h> /* for NULL */
#include <string.h> /* for strlen() */
#include <dos.h> /* for GETVECT() & MK_FP() */
#ifdef __TURBOC__
#define ASM asm
#define GETVECT getvect
#else
/* assume Microsoft C if not Turbo/Borland C */
#define ASM _asm
#define GETVECT _dos_getvect
#endif
/* some compilers don't have this */
#ifndef MK_FP
#define MK_FP(seg, offset) (void far *)(((unsigned long)seg << 16) \
+ (unsigned long)(unsigned)offset)
#endif
/*
Some useful definitions
*/
typedef void (far * FuncPtr)(void);
typedef char far * DataPtr;
/*
Pointers to the LSL entry points
*/
static FuncPtr LSLentry = NULL;
static FuncPtr LSLProtocolAPI = NULL;
static FuncPtr LSLGeneralAPI = NULL;
/*
DetectLSL detects if LSL is present and fills in
the API entry points above.
*/
static int CallMultiplex( unsigned int funCode, FuncPtr * lslEntry, DataPtr * lslSig );
static int IsEqual( char far * first, char far * second, int len );
static int DetectLSL( void )
{
unsigned long int2Fvector;
int returnCode;
unsigned int multiplex;
static char lslSignature[] = "LINKSUP$";
int lslSigLength = strlen( lslSignature ) - 1;
char far * lslSigPtr;
/* Need to put these two in a struct to guarantee they are
next to each other in memory */
struct {
FuncPtr LSLAPI1;
FuncPtr LSLAPI2;
} apiStruct;
/* if we've already been called, skip it */
if ( NULL != LSLentry )
return ( 1 );
/*
Make sure INT 2Fh is initialized. This is only
technically necessary to support DOS 2.x.
*/
int2Fvector = (unsigned long)GETVECT( 0x2F );
if ( 0UL == int2Fvector ) /* No INT 2Fh handler? */
return ( 0 ); /* then no LSL! */
/*
Loop through the possible multiplex numbers, looking
for the LINKSUP$ signature string to be returned by
one of them.
*/
for ( multiplex = 0xC0; multiplex <= 0xFF; multiplex++ ) {
returnCode = CallMultiplex( multiplex, &LSLentry, &lslSigPtr );
if ( ( 0xFF == returnCode ) && ( NULL != lslSigPtr ) ) {
if ( !IsEqual( lslSignature, lslSigPtr, lslSigLength ) )
LSLentry = NULL; /* make sure it stays NULL */
else {
ASM {
push si /* Save C registers */
mov ax,ss
mov es,ax
lea si,apiStruct /* ES:SI -> apiStruct */
mov bx,2 /* Func 2: retrieve entry points */
call LSLentry
pop si /* Restore C registers */
}
LSLProtocolAPI = apiStruct.LSLAPI1;
LSLGeneralAPI = apiStruct.LSLAPI2;
break; /* break out of for loop! */
} /* if signature found */
} /* if multiplex call succeeded */
} /* for each possible multiplex */
return ( NULL != LSLentry );
} /* DetectLSL() */
/*
CallMultiplex calls INT 2Fh and returns the appropriate pointers.
*/
static int CallMultiplex( unsigned int funCode, FuncPtr * lslEntry, DataPtr * lslSig )
{
int returnCode, retES, retSI, retDX, retBX;
ASM {
xor si,si /* Zero out all return registers */
mov es,si
mov bx,si
mov dx,si
mov ax,funCode
xchg ah,al
int 2fh
xor ah,ah
mov returnCode,ax
mov retES,es
mov retSI,si
mov retDX,dx
mov retBX,bx
}
*lslSig = MK_FP( retES, retSI );
*lslEntry = (FuncPtr)MK_FP( retDX, retBX );
return ( returnCode );
} /* CallMultiplex() */
/*
IsEqual returns 1 if two strings are equal, zero otherwise.
We could use strcmp(), but since we need to compare with
strings that reside in TSR's (like "LINKSUP$") then that
restricts us to a large memory model. Rolling our own allows
this code to be compiled in any memory model.
*/
static int IsEqual( char far * first, char far * second, int len )
{
int returnCode;
ASM {
push ds /* Save C's registers */
push di
push si
les di,first
lds si,second
mov cx,len
cld
repe cmpsb
pushf /* put flags into AX */
pop ax
pop si /* Restore C's registers */
pop di
pop ds
mov returnCode,ax
}
return ( returnCode & 0x0040 ); /* return state of ZERO flag */
} /* IsEqual() */
/*
GetLSLVersion() returns the LSL version number if present,
0 if it is not loaded.
To get the version number, we must obtain a pointer to the
LSL Configuration Table, by calling function 12 on the
LSL Protocol support API. We can then retrieve information
from inside that struct.
*/
typedef struct {
unsigned char ConfigMajorVer;
unsigned char ConfigMinorVer;
unsigned long NumLSLReceiveBuffers;
unsigned long ReceiveBufferSize; /* not including ECB */
unsigned char LSLMajorVersion;
unsigned char LSLMinorVersion;
int MaxBoardsNum;
int MaxStacksNum;
char reserved2[ 12 ];
} LSLConfig;
int GetLSLVersion( int * maxBoards, int * maxStacks )
{
int lslVer;
int retES, retSI;
LSLConfig far * lslConfPtr;
if ( !DetectLSL() )
return ( 0 );
ASM {
push si /* save C registers */
xor si,si /* zero return values */
mov es,si
mov bx,0019h /* Func 19: GetLSLConfiguration */
call LSLProtocolAPI
mov retES,es
mov retSI,si
pop si
}
lslConfPtr = MK_FP( retES, retSI ); /* point to config struct */
if ( NULL == lslConfPtr )
return ( 0 );
/* Pack the version number into the return value */
lslVer = ( lslConfPtr->LSLMajorVersion << 8 ) |
lslConfPtr->LSLMinorVersion;
/* return the maximum number of boards & stacks it can take */
*maxBoards = lslConfPtr->MaxBoardsNum;
*maxStacks = lslConfPtr->MaxStacksNum;
return ( lslVer );
} /* GetLSLVersion() */
/*
GetModuleConfig is an internal routine used by GetMLIDConfig
and GetProtocolConfig.
Use one of the two #defines below as the value of funCode,
to choose whether you are looking for an MLID or a Protocol.
*/
#define GET_MLID_CONTROL (0x0012)
#define GET_PROTOCOL_CONTROL (0x0013)
/* return values */
#define GMC_SUCCESS (int)(0)
#define GMC_NO_MORE_ITEMS (int)(0x8003) /* not found & none beyond */
#define GMC_ITEM_NOT_PRESENT (int)(0x8004) /* not found, but might be more */
FuncPtr ModuleAPI = NULL;
static int GetModuleConfig( int funCode, int whichOne, DataPtr * configTable )
{
int retES, retSI, returnCode;
if ( !DetectLSL() )
return ( 0 );
ASM {
push si /* save C's registers */
xor si,si
mov es,si /* zero out return value */
mov bx,funCode /* func number 12 or 13 */
mov ax,whichOne /* board # or protocol # */
call LSLProtocolAPI
mov returnCode,ax /* return code */
mov retES,es /* returned pointer */
mov retSI,si
pop si /* restore C's registers */
}
if ( GMC_SUCCESS == returnCode ) {
/*
We got the module control API for this MLID or Protocol.
Call it with function 0 to retrieve the module's
configuration table.
*/
ModuleAPI = (FuncPtr)MK_FP( retES, retSI ); /* make a ptr to their API */
ASM {
push si /* save C's registers */
xor si,si
mov es,si /* zero out return value */
xor bx,bx /* func 0 is always Get Config Table */
mov ax,whichOne /* logical board # when calling MLIDs */
call ModuleAPI
mov retES,es /* returned pointer */
mov retSI,si
pop si /* restore C's registers */
}
*configTable = MK_FP( retES, retSI );
} /* if we found the protocol or MLID */
return ( returnCode );
} /* GetModuleConfig() */
/*
GetMLIDConfig returns a pointer to the configuration table
for a given MLID. Pass in the MLID number desired.
*/
typedef struct {
char Signature[ 26 ]; /* always "HardwareDriverMLID" */
unsigned char ConfigTableMajorVer;
unsigned char ConfigTableMinorVer;
unsigned char NodeAddress[ 6 ];
unsigned int ModeFlags;
unsigned int BoardNumber;
unsigned int BoardInstance;
unsigned int MaxPacketSize;
unsigned int BestDataSize;
unsigned int WorstDataSize;
char far * CardLongName;
char far * CardShortName;
char far * FrameString;
char Reserved0[ 2 ];
unsigned int FrameID;
unsigned int TransportTime;
void far * RouteHandler;
unsigned int LookAheadSize;
unsigned int LineSpeed;
unsigned int QueueDepth;
char Reserved1[ 6 ];
unsigned char MLIDMajorVer;
unsigned char MLIDMinorVer;
unsigned int Flags;
unsigned int SendRetries;
void far * Link;
unsigned int SharingFlags;
unsigned int Slot;
unsigned int IOAddress1;
unsigned int IORange1;
unsigned int IOAddress2;
unsigned int IORange2;
unsigned long MemoryAddress1;
unsigned int MemorySize1;
unsigned long MemoryAddress2;
unsigned int MemorySize2;
unsigned char IntLine1;
unsigned char IntLine2;
unsigned char DMALine1;
unsigned char DMALine2;
} MLIDConfigTable;
typedef MLIDConfigTable far * MLIDPtr;
int GetMLIDConfig( int boardNumber, MLIDPtr * configPtr )
{
return( GetModuleConfig( GET_MLID_CONTROL, boardNumber,
(DataPtr *)configPtr ) );
} /* GetMLIDConfig() */
/*
GetProtocolConfig returns a pointer to the configuration table
for a given protocol. Pass in the protocol
number desired.
*/
typedef struct {
unsigned char ConfigTableMajorVer;
unsigned char ConfigTableMinorVer;
char far * ProtocolLongName;
char far * ProtocolShortName;
unsigned char ProtocolMajorVer;
unsigned char ProtocolMinorVer;
char ConfigTableReserved[ 16 ];
} ProtocolConfigTable;
typedef ProtocolConfigTable far * ProtocolPtr;
int GetProtocolConfig( int protoNumber, ProtocolPtr * configPtr )
{
return( GetModuleConfig( GET_PROTOCOL_CONTROL, protoNumber,
(DataPtr *)configPtr ) );
} /* GetProtocolConfig() */
/*
GetNetCfgPath returns a copy of the full path where the
NET.CFG file was loaded.
*/
char * GetNetCfgPath( void )
{
int retDS, retDX;
static char netCfgBuff[ 81 ] = "";
char far * netCfg;
int i;
if ( !DetectLSL() )
return ( NULL );
ASM {
push ds
mov bx,0007h /* Func 7: Get NET.CFG Path */
call LSLGeneralAPI
mov retDS,ds
mov retDX,dx
pop ds
}
netCfg = MK_FP( retDS, retDX );
/*
Have to copy this ourselves because we might be in
small model, so strcpy() won't handle the far *.
*/
i = 0;
while ( 0 != ( netCfgBuff[ i ] = netCfg[ i ] ) )
i++;
return ( netCfgBuff );
} /* GetNetCfgPath() */
/* eof: VERODI.C */